//=============================================================================
// XBus 
//-----------------------------------------------------------------------------
// File        : daemon.c
// Description : 
// Author      : Ismail Sabry
// Date        : 1/30/2009
//=============================================================================
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#include <xbus.h>
#include <xbus_init.h>

int get_option(t_XBUS_info *info, int argc, char **argv);

int init_info(t_XBUS_info *info);
int check_info(t_XBUS_info *info);

static int alive=1;

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void catch_signal(int sig)
{
  alive = 0;
  printf(" \nSTOP (sig %d) \n\n", sig);
  fflush(stdout);
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int main (int argc, char **argv)
{
  int               i;
  t_XBUS_info       info;

  init_info(&info);

  if( get_option(&info, argc, argv) == -1) {
    return -1;
  }

  if( check_info(&info) == -1) {
    return -1;
  }
  signal(SIGKILL,  catch_signal); 
  signal(SIGINT,  catch_signal);
  signal(SIGQUIT, catch_signal);
  signal(SIGTERM, catch_signal);
  
  if( XBUS_create(&info) == -1)
    return -1;
  
  printf("Start XBUS ...\n  ");
  fflush(stdout);
  while(alive) {
#if 0
    for(i=0; i<info.nb_module; i++) {
      if(!alive) break;
      printf("X"); fflush(stdout); sleep(1);
    }
    for(i=0; i<info.nb_module; i++) {
      if(!alive) break;
      printf("\b \b"); fflush(stdout); sleep(1);
    }
#endif
   sleep(1);
  }


  printf("Stop XBUS ...\n  ");
  XBUS_remove(&info);

  return 0;

}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int get_option(t_XBUS_info *info, int argc, char **argv)
{
  int      ret=0;
  int      c;
  
  opterr = 0;

  if(argc != 9) {
    ret = -1;
  } else {
    while ((c = getopt (argc, argv, "n:m:c:s:?")) != -1) {
      switch (c) {
      case 'n': 
	// xbus name
	snprintf(info->name, XBUS_SIZE_NAME-1, "%s", optarg);
	break;
      case 'm': 
	// nb modules
	info->nb_module = atoi(optarg);
	break;
      case 'c': 
	// nb cells
	info->nb_cell = atoi(optarg);
	break;
      case 's': 
	// size cell
	info->size_cell = atoi(optarg);
	break;
      case '?':
	ret = -1;
	break;
      default:
	ret = -1;
	break;
      }    
    }
  }
  
  if(ret != 0) {
    printf("\n");
    printf(" syntax: %s -n <name> -m <nbm> -c <nbc> -s <sc>\n", argv[0]);
    printf("    -n  xbus name\n");
    printf("    -m  number of modules\n");
    printf("    -c  number of cells per modules \n");
    printf("    -s  cell size (in bytes) \n");
    printf("    -?  this message \n");
    printf("\n");
  }
  
  return(ret);
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int init_info(t_XBUS_info *info)
{
  memset(info, 0, sizeof(t_XBUS_info));
  return 0;
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int check_info(t_XBUS_info *info)
{
  int   len, ret=0;
  
  len = strlen(info->name);
  if( (len < XBUS_NIM_SIZE_NAME ) || 
      (len > XBUS_MAX_SIZE_NAME) ) {
    printf("XBus invalid name size [%d ... %d] bytes \n", 
	   XBUS_NIM_SIZE_NAME,XBUS_MAX_SIZE_NAME );
    ret = -1;
  }

  if( (info->nb_module < XBUS_MIN_NB_MODULE) || 
      (info->nb_module > XBUS_MAX_NB_MODULE) ) {
    printf("XBus invalid Nb Modules %d [%d ... %d] \n", info->nb_module, 
	   XBUS_MIN_NB_MODULE, XBUS_MAX_NB_MODULE );
    ret = -1;
  }

  if( (info->nb_cell < XBUS_MIN_NB_CELL) || 
      (info->nb_cell > XBUS_MAX_NB_CELL) ) {
    printf("XBus invalid Nb Cells %d [%d ... %d] \n", info->nb_cell,
	   XBUS_MIN_NB_CELL, XBUS_MAX_NB_CELL );
    ret = -1;
  }
  
  if( (info->size_cell < XBUS_MIN_SIZE_CELL) || 
      (info->size_cell > XBUS_MAX_SIZE_CELL) ) {
    printf("XBus invalid Cell size %d [%d ... %d] \n", info->size_cell,
	   XBUS_MIN_SIZE_CELL,XBUS_MAX_SIZE_CELL ); 
    ret = -1;
  } 

  return(ret);
}
